Transactions are a fundamental building block for reliable concurrent systems. They enable programmers to express a unit of work which a system will perform, and provide guarantees on how that unit of work will be executed with respect to other transactions in the system. In a distributed system, multiple clients can simultaneously request transactions, and these transactions can sometimes conflict with each other, depending on the guarantees provided by the system. For instance, two transactions in an object store can try to modify the same object. In most systems, a transaction manager can be used detect such conflicts and can abort one of the transactions to maintain correctness. Conventional systems typically achieve this through the use of locks or write-ahead logging, global logging and the like, or otherwise can relax certain guarantees provided by the system. Locking and write-ahead logging require considerable overhead, which can hamper throughput and increase latency, and thus can be deemed “heavyweight” processes for this reason. Global logging, on the other hand, is a technique where conflict resolution is derived from recording every transaction on a single global log. Global logging imposes a burden on the client with having to perform their own transaction resolution. Since no entity maintains the latest version of each object, the client must playback the entire log to find the latest versions of each object of interest in order to determine whether or not a conflict occurs. In addition, aborted transactions can be logged which can slow the playback process and greatly limit the scalability of the system as the number of clients grow.